const PENDING = "pending"
const RESOLVED = "resolved"
const REJECTED = "rejected"

function Promise(excutor) {
    this.status = PENDING // 新建的Promise实例都是pending状态
    this.data = undefined // 保存成功或者失败的值
    this.callback = []
    let that = this
    function resolve(value) {
        // 不是pending状态不在修改
        if (that.status !== PENDING) return
        // 修改状态
        that.status = RESOLVED
        that.data = value
        // 执行回调
        if (that.callback.length > 0) {
            // 异步执行
            setTimeout(function () {
                that.callback.forEach(_i => {
                    _i.onResolved(value)
                })
            })
        }
    }
    function reject(value) {
        if (that.status !== PENDING) return
        // 修改状态
        that.status = REJECTED
        that.data = value
        // 执行回调
        if (that.callback.length > 0) {
            // 异步执行
            setTimeout(function () {
                that.callback.forEach(_i => {
                    _i.onRejected(value)
                })
            })
        }
    }
    excutor(resolve, reject)
}

Promise.prototype.then = function (onResolved, onRejected) {

    // 返回一个promise
    return new Promise((resolve, reject) => {
        function handle(cb) {
            // 当前函数用于执行传入的回调函数，拿到回调函数的返回值，然后resolve或reject
            try {
                const res = cb(that.data) // 拿到传入的回调的返回值，对于返回值进行验证，主要是对于promise进行处理
                if (res instanceof Promise) { 
                    // 调用then对于状态再次进行处理
                    res.then(value => resolve(value), reason => reject(reason))
                }

            } catch (error) {
                reject(error)
            }
        }


        if (this.status === PENDING) {
            this.callback.push({
                onResolved() {
                    handle(onResolved)
                },
                onRejected() {
                    handle(onRejected)
                }
            })
        } else if(this.status === RESOLVED){
            onResolved = typeof onResolved == "function" ? onResolved:value => value
            setTimeout(() => {
                handle(onResolved)
            })
    
        } else if(this.status === REJECTED){
            onRejected = typeof onRejected == "function" ? onRejected:reason => reason
            setTimeout(() => {
                handle(onRejected)
            })
        }
    })
}

function test() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(10)
        }, 1000)
    })
}

test.then(
    (data) => { console.log(data) },
    (reason) => { console.log(reason) }
)
